/*
 * JVM.c
 *
 *  Created on: 10.12.2010
 *      Author: Tavin
 */
#include <stdint.h>
#include <stdio.h>
#include <string.h>



#include "JVM_Statuscodes.h"
#include "JVM.h"
#include "JVM_ClassTable.h"
#include "JVM_CP_Table.h"
#include "JVM_Handle.h"
#include "JVM_Thread.h"
#include "JVM_Opcode.h"




const char  mainString []="main";
const char  clinitString []="<clinit>";

void JVM_init()
{
	uint16_t classCounter;
	uint16_t handleNumber;
	uint16_t dataSize;


	JVM_Class_t * myClass;


	JVM_Handle_Init();
	//TODO clean HEAP
	JVM_Thread_init();

	for (classCounter=0;classCounter<JVM_ClassTable_size();classCounter++)
		{
		myClass=JVM_ClassTable_get(classCounter);
		handleNumber=JVM_Class_getStaticDataHandle(myClass);
		dataSize=JVM_Class_getStaticDataSize(myClass)+sizeof(JVM_Class_t*);
		JVM_Handle_set(handleNumber,dataSize);
		JVM_Handle_setClass(handleNumber,myClass);
		JVM_Handle_countUp(handleNumber);

		JVM_Class_InitFields(myClass); // TODO status if fails !!
		}

	for (classCounter=0;classCounter<JVM_ClassTable_size();classCounter++)
		{

		uint16_t methodsCount;
		uint16_t methodCounter;
		uint16_t nameIndex;

		JVM_Method_t * tmpMethod;
		JVM_CP_UTF8_t * tmpUtf8Info;
		JVM_Thread_t * myThread;


		myClass=JVM_ClassTable_get(classCounter);
		methodsCount=JVM_Class_getMethodCount(myClass);

		for (methodCounter=0;methodCounter<methodsCount;methodCounter++)
			{
			tmpMethod=JVM_Class_getMethod(myClass,methodCounter);
			nameIndex=JVM_Method_getNameIndex(tmpMethod);

			tmpUtf8Info=JVM_CPTable_getUtf8Info(myClass->constantPoolTable,nameIndex);

			// Main
			if (memcmp( tmpUtf8Info->data,mainString,4)==0)
				{



				myThread=JVM_Thread_newThread(myClass,tmpMethod);
				JVM_Thread_setWaiting(myThread);
				}

			// Class init
			else if (memcmp( tmpUtf8Info->data,clinitString,8)==0)
				{

				myThread=JVM_Thread_newThread(myClass,tmpMethod);


				JVM_Thread_setActive(myThread);

				JVM_Thread_executeClassInitThread();

				JVM_Thread_remove(myThread);
				JVM_Thread_killThread(myThread);

				// kill Thread

				}


			}

		}

	JVM_Thread_setActive(threadList);
}



void JVM_run()
{
	JVM_Thread_countDownSleep();
	JVM_Thread_executeActiveThread();
}
